#! /usr/bin/python3
# -*- coding: UTF-8 -*-
  
'''※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
File Name: Short_video_processing.py
Author: GID5564
Description: 短视频二次创作
Version: 1.0
Created Time: 05/05/24-19:38:46
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
'''
import os
import subprocess
from pathlib import Path
from moviepy.editor import VideoFileClip, vfx,CompositeVideoClip,concatenate_videoclips

def get_videos(folder_path):   
    """
    获取当前目录下所有视频    
    :param folder_path: 视频所在目录路径
    :return video_files:所有视频的路径
    """
    # 设置视频文件的常见扩展名    
    video_extensions = ['mp4', 'avi', 'mov', 'mkv', 'wmv', 'flv']
    video_files = []
    for filename in os.listdir(folder_path):        
        if any(filename.endswith(f".{ext}") for ext in video_extensions):            
            video_files.append(os.path.join(folder_path, filename))
    return video_files
    
def get_split_times(video_path, split_count):
    """
    获取视频分割点
    :param video_path: 视频所在目录路径
    :param split_count: 视频分割的数量
    :return split_times: 视频分割点
    """
    
    # 读取视频文件
    with VideoFileClip(video_path) as video:
        # 获取视频的总时长
        total_duration = video.duration

    # 计算每个分割点的时间，最后一个分割点是视频的总时长
    split_times = [total_duration * (i / split_count) for i in range(split_count + 1)]

    return split_times

def video_splits(video_path, split_times, save=None):
    """
    视频分割
    :param video_path: 视频所在目录路径
    :param split_times: 视频分割点（单位：秒）
    :param output_dir: 分割的子视频目录路径
    :return clips: 视频片段列表
    """
    video=VideoFileClip(video_path) 
    # 使用列表推导式生成子视频片段列表
    clips = [video.subclip(split_times[i], split_times[i + 1]) for i in range(len(split_times) - 1)]
    if save:
        #获取当前工作目录的绝对路径
        output_dir = os.path.join(Path().absolute(),"caches")
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        # 保存每个子视频片段到单独的文件
        for i, clip in enumerate(clips):
            clip.write_videofile(os.path.join(output_dir, f"video_clips_{i}.mp4"))
    return clips

def adjust_video_clip(clips, split_times, speed="",bright=0.5,save=None):
    """
    对视频片段进行变速处理和画面亮度调整
    :param video_path: 视频所在目录路径
    :param split_times: 视频分割点
    :param speed: 视频分割点，
        整数:
            0:减半;1:正常;2:加倍;3:三倍
        浮点数:
            区问[1,2]间微调
    :param bright: 区间[0,1]，百分比

    :param output_dir: 分割的子视频目录路径
    :return speed_up_clips: 经处理的视频片段列表
    """

    # 定义速度值列表
    
    if isinstance(speed,int):
        assert speed>=0 and speed<=3,"参数三取值错误，区间[0,3]"
        speed_list= [0.5,1.0,1.5,2.0]
        speed_values = [speed_list[speed]] * len(split_times)
    elif isinstance(speed,float):
        assert speed>=0 and speed<=100,"参数三取值错误，区间[0.0,100.0]"

        v=1.0+0.01*speed
        speed_values = [v] * len(split_times)
    else:
        speed_values = [1.05] * len(split_times)

    # 亮度
    assert bright>=0 and bright<=1,"参数三取值错误，区间[0.0,1.0]"
    

    # 对每个片段进行变速处理，设置为105%速度、画面亮度调整（50%）
    #speed_values = [1.05] * len(split_times)
    speed_up_clips = [clip.fx(vfx.speedx, factor=speed_values[index]).fx(vfx.colorx,bright) for index, clip in enumerate(clips)]
    
    if save:
        #获取当前工作目录的绝对路径
        output_dir = os.path.join(Path().absolute(),"caches")
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        # 保存处理后的视频片段
        for index, speed_up_clip in enumerate(speed_up_clips):
            speed_up_clip.write_videofile(os.path.join(output_dir,f"output_{index}.mp4"))
    
    return speed_up_clips



def export_composite_to_ffmpeg(clips, output_dir):
    """
    将处理后的视频片段合并在一起写入到一个新的文件中    
    :param clips: 经处理的视频片段列表
    :param output_dir: 新视频目录路径
    :return 
    """
    
    # 创建临时目录
    temp_dir="temp_clips"
    if not os.path.exists(temp_dir):
        os.makedirs(temp_dir)

    # 导出每个剪辑为临时文件
    temp_files = []
    for i, clip in enumerate(clips):
        temp_file = os.path.join(temp_dir, f"clip_{i}.mp4")
        clip.write_videofile(temp_file,threads=6,preset='ultrafast')
        temp_files.append(temp_file)

    # 创建 ffmpeg concat 文件
    ffmpeg_files = "files.txt"
    with open(ffmpeg_files, 'w') as f:
        for tf in temp_files:
            f.write(f"file '{tf}'"+ os.linesep)
            
    output_path = os.path.join(output_dir, f"video(new).mp4")

    # 使用 ffmpeg concat 协议合并视频
    ffmpeg_command = f"ffmpeg -f concat -safe 0 -i {ffmpeg_files} -c copy \"{output_path}\" -y"
    os.system(ffmpeg_command)
    
    # 清理临时文件
    for tf in temp_files:
        os.remove(tf)
    os.remove(ffmpeg_files)
    

def export_composite_to_concatenate(clips, output_dir):
    """
    将处理后的视频片段合并在一起写入到一个新的文件中    
    :param clips: 经处理的视频片段列表
    :param output_dir: 新视频目录路径
    """
    
    # 创建临时目录
    temp_dir = "temp_clips"
    if not os.path.exists(temp_dir):
        os.makedirs(temp_dir)
    
    # 导出每个剪辑为临时文件
    temp_files = []
    for i, clip in enumerate(clips):
        temp_file = os.path.join(temp_dir, f"clip_{i}.mp4")
        #clip.write_videofile(temp_file, threads=4, audio=False, logger=None, preset='ultrafast')
        temp_files.append(temp_file)
    
    # 使用 moviepy 库的 concatenate_videoclips 函数合并视频
    final_clip = concatenate_videoclips(clips)
    output_path = os.path.join(output_dir, f"video(new).mp4")
    final_clip.write_videofile(output_path, threads=6,preset='ultrafast')

    # 清理临时文件
    for tf in temp_files:
        os.remove(tf)
    os.rmdir(temp_dir)




if __name__ == "__main__":
    video_dir="/home/AA"
    output_dir="/home/save"
    video_path=get_videos(video_dir)
    #print(video_path)
    split_times=get_split_times(video_path[0],4)
    #print(split_times)
    clips=video_splits(video_path[0],split_times)

    clips=adjust_video_clip(clips,split_times)
    print("时间有点长，请耐心等待，合成中……")
    #export_composite_to_concatenate(clips,output_dir)
    export_composite_to_ffmpeg(clips,output_dir)



































